home *** CD-ROM | disk | FTP | other *** search
- RCS_ID_C="$Id: amiga_sendrecv.c,v 3.1 1994/01/06 13:37:15 too Exp $";
- /*
- * Copyright (c) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
- * Helsinki University of Technology, Finland.
- * All rights reserved.
- *
- * Created: Wed Jan 5 18:35:27 1994 too
- * Last modified: Thu Jan 6 15:20:11 1994 too
- *
- * HISTORY
- * $Log: amiga_sendrecv.c,v $
- * Revision 3.1 1994/01/06 13:37:15 too
- * Moved send and recv functions from amiga_syscalls.c for
- * easier update
- *
- */
-
- #include <conf.h>
-
- #include <sys/param.h>
- #include <sys/systm.h>
- #include <sys/malloc.h>
- #include <sys/mbuf.h>
- #include <sys/protosw.h>
- #include <sys/socket.h>
- #include <sys/socketvar.h>
- #include <sys/synch.h>
- #include <sys/errno.h>
-
- #include <exec/types.h>
- #include <exec/libraries.h>
- #include <exec/semaphores.h>
-
- #include <api/amiga_api.h>
- #include <api/amiga_libcallentry.h>
- #include <api/sockargs.h>
-
- #include <kern/uipc_socket_protos.h>
- #include <kern/uipc_socket2_protos.h>
-
- static LONG sendit(struct SocketBase * p,
- LONG s,
- struct msghdr * mp,
- LONG flags,
- LONG * retsize);
-
- static LONG recvit(struct SocketBase * p,
- LONG s,
- struct msghdr * mp,
- LONG flags,
- LONG * namelenp,
- LONG * retsize);
-
-
- LONG SAVEDS RAF5(_send,
- struct SocketBase *, libPtr, a6,
- LONG, s, d0,
- caddr_t, buf, a0,
- LONG, len, d1,
- LONG, flags, d2)
- #if 0
- {
- #endif
-
- struct msghdr msg;
- struct iovec aiov;
- LONG error, retval;
-
- CHECK_TASK();
-
- msg.msg_name = 0;
- msg.msg_namelen = 0;
- msg.msg_iov = &aiov;
- msg.msg_iovlen = 1;
- msg.msg_control = 0;
- aiov.iov_base = buf;
- aiov.iov_len = len;
-
- ObtainSyscallSemaphore(libPtr);
- error = sendit(libPtr, s, &msg, flags, &retval);
- ReleaseSyscallSemaphore(libPtr);
-
- API_STD_RETURN(error, retval);
- }
-
- LONG SAVEDS RAF7(_sendto,
- struct SocketBase *, libPtr, a6,
- LONG, s, d0,
- caddr_t, buf, a0,
- LONG, len, d1,
- LONG, flags, d2,
- caddr_t, to, a1,
- LONG, tolen, d3)
- #if 0
- {
- #endif
-
- struct msghdr msg;
- struct iovec aiov;
- LONG error, retval;
-
- CHECK_TASK();
-
- msg.msg_name = to;
- msg.msg_namelen = tolen;
- msg.msg_iov = &aiov;
- msg.msg_iovlen = 1;
- msg.msg_control = 0;
- aiov.iov_base = buf;
- aiov.iov_len = len;
-
- ObtainSyscallSemaphore(libPtr);
- error = sendit(libPtr, s, &msg, flags, &retval);
- ReleaseSyscallSemaphore(libPtr);
-
- API_STD_RETURN(error, retval);
- }
-
- LONG SAVEDS RAF4(_sendmsg,
- struct SocketBase *, libPtr, a6,
- LONG, s, d0,
- struct msghdr *, msg_p, a0,
- LONG, flags, d1)
- #if 0
- {
- #endif
- LONG error, retval;
-
- CHECK_TASK();
-
- ObtainSyscallSemaphore(libPtr);
- error = sendit(libPtr, s, msg_p, flags, &retval);
- ReleaseSyscallSemaphore(libPtr);
-
- API_STD_RETURN(error, retval);
- }
-
- static LONG sendit(struct SocketBase * p,
- LONG s,
- struct msghdr * mp,
- LONG flags,
- LONG * retsize)
- {
- struct socket *so;
- struct uio auio;
- register int i;
- register struct iovec *iov;
- struct mbuf *to, *control;
- LONG len, error;
-
- if (error = getSock(p, s, &so))
- return (error);
-
- auio.uio_iov = mp->msg_iov;
- auio.uio_iovcnt = mp->msg_iovlen;
- auio.uio_procp = p;
- auio.uio_resid = 0;
- iov = mp->msg_iov;
-
- for(i = 0; i < mp->msg_iovlen; i++, iov++) {
- if (iov->iov_len < 0)
- return (EINVAL);
- if ((auio.uio_resid += iov->iov_len) < 0)
- return (EINVAL);
- }
-
- if (mp->msg_name) {
- if (error = sockArgs(&to, mp->msg_name, mp->msg_namelen, MT_SONAME))
- return (error);
- }
- else
- to = 0;
-
- if (mp->msg_control) {
- if (mp->msg_controllen < sizeof (struct cmsghdr)) {
- error = EINVAL;
- goto bad;
- }
- if (error = sockArgs(&control, mp->msg_control,
- mp->msg_controllen, MT_CONTROL))
- goto bad;
- }
- else
- control = 0;
-
- len = auio.uio_resid;
- if (error = sosend(so, to, &auio, (struct mbuf *)0, control, flags)) {
- if (auio.uio_resid != len && (error == ERESTART || error == EINTR ||
- error == EWOULDBLOCK))
- error = 0;
- }
- if (error == 0)
- *retsize = len - auio.uio_resid;
-
- /* sosend() frees control if allocated */
- bad:
- if (to)
- m_freem(to);
-
- return (error);
- }
-
- LONG SAVEDS RAF5(_recv,
- struct SocketBase *, libPtr, a6,
- LONG, s, d0,
- caddr_t, buf, a0,
- LONG, len, d1,
- LONG, flags, d2)
- #if 0
- {
- #endif
-
- struct msghdr msg;
- struct iovec aiov;
- LONG error, retval;
-
- CHECK_TASK();
-
- msg.msg_name = 0;
- msg.msg_namelen = 0;
- msg.msg_iov = &aiov;
- msg.msg_iovlen = 1;
- msg.msg_control = 0;
- aiov.iov_base = buf;
- aiov.iov_len = len;
-
- ObtainSyscallSemaphore(libPtr);
- error = recvit(libPtr, s, &msg, flags, NULL, &retval);
- ReleaseSyscallSemaphore(libPtr);
-
- API_STD_RETURN(error, retval);
- }
-
- LONG SAVEDS RAF7(_recvfrom,
- struct SocketBase *, libPtr, a6,
- LONG, s, d0,
- caddr_t, buf, a0,
- LONG, len, d1,
- LONG, flags, d2,
- caddr_t, from, a1,
- LONG *, fromlenaddr, a2)
- #if 0
- {
- #endif
-
- struct msghdr msg;
- struct iovec aiov;
- LONG error, retval;
-
- CHECK_TASK();
-
- if (fromlenaddr)
- msg.msg_namelen = *fromlenaddr;
- else
- msg.msg_namelen = 0;
-
- msg.msg_name = from;
- msg.msg_iov = &aiov;
- msg.msg_iovlen = 1;
- msg.msg_control = 0;
- aiov.iov_base = buf;
- aiov.iov_len = len;
-
- ObtainSyscallSemaphore(libPtr);
- error = recvit(libPtr, s, &msg, flags, fromlenaddr, &retval);
- ReleaseSyscallSemaphore(libPtr);
-
- API_STD_RETURN(error, retval);
- }
-
- LONG SAVEDS RAF4(_recvmsg,
- struct SocketBase *, libPtr, a6,
- LONG, s, d0,
- struct msghdr *, msg_p, a0,
- LONG, flags, d1)
- #if 0
- {
- #endif
- LONG error, retval;
-
- CHECK_TASK();
-
- ObtainSyscallSemaphore(libPtr);
- error = recvit(libPtr, s, msg_p, flags, NULL, &retval);
- ReleaseSyscallSemaphore(libPtr);
-
- API_STD_RETURN(error, retval);
- }
-
- static LONG recvit(struct SocketBase * p,
- LONG s,
- struct msghdr * mp,
- LONG flags,
- LONG * namelenp,
- LONG * retsize)
- {
- struct socket * so;
- struct uio auio;
- struct iovec *iov;
- register int i;
- ULONG len;
- LONG error;
- struct mbuf *from = 0, *control = 0;
-
- if (error = getSock(p, s, &so))
- return (error);
-
- auio.uio_iov = mp->msg_iov;
- auio.uio_iovcnt = mp->msg_iovlen;
- auio.uio_procp = p;
- auio.uio_resid = 0;
-
- iov = mp->msg_iov;
- for(i = 0; i < mp->msg_iovlen; i++, iov++) {
- if (iov->iov_len < 0)
- return (EINVAL);
- if ((auio.uio_resid += iov->iov_len) < 0)
- return (EINVAL);
- }
- len = auio.uio_resid;
- if (error = soreceive(so, &from, &auio,
- (struct mbuf **)0, &control, (int *)&flags))
- if (auio.uio_resid != len && (error == ERESTART || error == EINTR ||
- error == EWOULDBLOCK))
- error = 0;
-
- if (error)
- goto out;
-
- *retsize = len - auio.uio_resid;
-
- if (mp->msg_name) {
- len = mp->msg_namelen;
- if (len <= 0 || from == 0)
- len = 0;
- else {
- if (len > from->m_len)
- len = from->m_len;
- aligned_bcopy(mtod(from, caddr_t), (caddr_t)mp->msg_name, (unsigned)len);
- }
- mp->msg_namelen = len;
- if (namelenp)
- *namelenp = len;
- }
- if (mp->msg_control) {
- len = mp->msg_controllen;
- if (len <= 0 || control == 0)
- len = 0;
- else {
- if (len >= control->m_len)
- len = control->m_len;
- /* else
- flags |= MSG_CTRUNC; no syscall ever does something w/ mp->flags */
-
- aligned_bcopy(mtod(control, caddr_t),
- (caddr_t)mp->msg_control, (unsigned)len);
- }
- mp->msg_controllen = len;
- }
- out:
- if (from)
- m_freem(from);
- if (control)
- m_freem(control);
-
- return (error);
- }
-